package cn.vc.media.service.impl;

import cn.vc.basicmodule.entity.Result;
import cn.vc.basicmodule.utils.StringUtil;
import cn.vc.media.entity.po.MediaFiles;
import cn.vc.media.mapper.MediaFilesMapper;
import cn.vc.media.service.MediaFileService;
import cn.vc.media.service.MinioFileService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.j256.simplemagic.ContentInfo;
import com.j256.simplemagic.ContentInfoUtil;
import io.minio.MinioClient;
import io.minio.UploadObjectArgs;
import io.minio.errors.*;
import io.minio.messages.DeleteError;
import io.minio.messages.DeleteObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.compress.utils.IOUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.*;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @description TODO
 * @author Mr.M
 * @date 2022/9/10 8:58
 * @version 1.0
 */
@Slf4j
@Service
public class MediaFileServiceImpl extends MinioFileService implements MediaFileService  {
    @Autowired
    private MinioClient minioClient;
    @Autowired
    private MediaFileService currentProxy;
    @Autowired
    private MediaFilesMapper mediaFilesMapper;

    // Minio IP地址
    @Value("${minio.ip}")
    private String ip;
    // 存储用户文件
    @Value("${minio.bucket.userfiles}")
    private String bucket_user;
    // 存储封面
    @Value("${minio.bucket.coverfiles}")
    private String bucket_cover;

    @Override
    public String uploadAvatar(Long userId, String fileName, String localFilePath) {
        // 先得到扩展名
        String extension = fileName.substring(fileName.lastIndexOf("."));
        // 得到mimeType
        String mimeType = getMimeType(extension);

        // user/{ID}/avatar/head.*
        // 对象名（路径+名称）
        String objectName = userId.toString()+"/avatar/head"+extension;
        // 上传文件到minio
        boolean result = this.addMediaFilesToMinio(localFilePath, mimeType, bucket_user, objectName);
        if (!result) {
            throw new RuntimeException("上传文件失败");
        }
        // 准备返回的对象
        return "http://"+this.ip+"/minio/"+bucket_user+"/"+objectName;
    }

    @Override
    public String uploadCover(String fileName, String localFilePath) {
        // 先得到扩展名
        String extension = fileName.substring(fileName.lastIndexOf("."));
        // 得到mimeType
        String mimeType = getMimeType(extension);

        // 文件的md5值
        String fileMd5 = getFileMd5(new File(localFilePath));
        if (StringUtil.isEmpty(fileMd5)) {
            log.error("fileMd5为空！");
        }
        // 对象名（路径+名称）
        String objectName = getFilePathByMd5(fileMd5, extension);
        // 上传文件到minio
        boolean result = this.addMediaFilesToMinio(localFilePath, mimeType, bucket_cover, objectName);
        if (!result) {
            throw new RuntimeException("上传文件失败");
        }
        // 准备返回的对象
        return "http://"+this.ip+"/minio/"+bucket_cover+"/"+objectName;
    }

    @Override
    public MediaFiles selectById(Long id) {
        MediaFiles mediaFiles = mediaFilesMapper.selectById(id);
        if (mediaFiles==null) {
            log.error("文件信息为空！id={}", id);
            throw new RuntimeException("文件信息为空！id="+id);
        }
        return mediaFiles;
    }

    @Override
    public List<MediaFiles> selectByIds(List<Long> ids) {
        List<MediaFiles> mediaFilesList = new ArrayList<>();
        ids.forEach(id -> {
            mediaFilesList.add(mediaFilesMapper.selectById(id));
        });
        return mediaFilesList;
    }


    /**
     * 得到合并后的文件的地址
     * @param fileMd5 文件id即md5值
     * @param fileExt 文件扩展名
     * @return
     */
    private String getFilePathByMd5(String fileMd5, String fileExt){
        return fileMd5.charAt(0) + "/" + fileMd5.charAt(1) + "/" + fileMd5 + "/" +fileMd5 +fileExt;
    }

    // 根据扩展名获取mimeType
    private String getMimeType(String extension) {
        if (extension==null) {
            extension = "";
        }
        // 通过扩展名得到媒体资源类型 mimeType
        ContentInfo extensionMatch = ContentInfoUtil.findExtensionMatch(extension);
        String mimeType = MediaType.APPLICATION_OCTET_STREAM_VALUE; // 通用mimeType，字节流
        if (extensionMatch!=null) {
            mimeType = extensionMatch.getMimeType();
        }
        return mimeType;
    }

    // 获取文件的md5
    private String getFileMd5(File file) {
        try(FileInputStream fileInputStream =  new FileInputStream(file)) {
            String fileMd5  = DigestUtils.md5Hex(fileInputStream);
            return fileMd5;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

}
